home *** CD-ROM | disk | FTP | other *** search
- Subject: v25i011: trn 2.0 - threaded newsreader based on rn 4.4, Part08/13
- Newsgroups: comp.sources.unix
- Approved: vixie@pa.dec.com
-
- Submitted-by: davison@borland.com (Wayne Davison)
- Posting-number: Volume 25, Issue 11
- Archive-name: trn/part08
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 8 (of 13)."
- # Contents: art.c common.h term.c
- # Wrapped by vixie@cognition.pa.dec.com on Tue Dec 3 16:34:55 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'art.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'art.c'\"
- else
- echo shar: Extracting \"'art.c'\" \(25485 characters\)
- sed "s/^X//" >'art.c' <<'END_OF_FILE'
- X/* $Id: art.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
- X *
- X *
- X *
- X */
- X/* This software is Copyright 1991 by Stan Barber.
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X */
- X
- X#include "EXTERN.h"
- X#include "common.h"
- X#include "rn.h"
- X#include "ngstuff.h"
- X#include "ngdata.h"
- X#include "head.h"
- X#include "cheat.h"
- X#include "help.h"
- X#include "search.h"
- X#include "artio.h"
- X#include "ng.h"
- X#include "bits.h"
- X#include "final.h"
- X#include "artstate.h"
- X#include "rcstuff.h"
- X#include "term.h"
- X#include "sw.h"
- X#include "util.h"
- X#include "backpage.h"
- X#include "intrp.h"
- X#ifdef USETHREADS
- X#include "threads.h"
- X#include "rthreads.h"
- X#endif
- X#include "INTERN.h"
- X#include "art.h"
- X
- X/* page_switch() return values */
- X
- X#define PS_NORM 0
- X#define PS_ASK 1
- X#define PS_RAISE 2
- X#define PS_TOEND 3
- X
- bool special = FALSE; /* is next page special length? */
- int slines = 0; /* how long to make page when special */
- ART_LINE highlight = -1; /* next line to be highlighted */
- char *restart = Nullch; /* if nonzero, the place where last */
- X /* line left off on line split */
- char *blinebeg; /* where in buffer current line began */
- ART_POS alinebeg; /* where in file current line began */
- X
- X#ifdef INNERSEARCH
- ART_POS innersearch = 0; /* artpos of end of line we found */
- X /* for 'g' command */
- ART_LINE isrchline = 0; /* last line to display */
- bool hide_everything = FALSE;
- X /* if set, do not write page now, */
- X /* but refresh when done with page */
- COMPEX gcompex; /* in article search pattern */
- X#endif
- X
- bool firstpage; /* is this the 1st page of article? */
- X
- char art_buf[LBUFLEN]; /* place for article lines */
- X
- void
- art_init()
- X{
- X ;
- X}
- X
- int
- do_article()
- X{
- X register char *s;
- X ART_POS artsize; /* size in bytes of article */
- X bool hide_this_line = FALSE; /* hidden header line? */
- X ART_LINE linenum; /* line # on page, 1 origin */
- X#ifdef ULSMARTS
- X bool under_lining = FALSE;
- X /* are we underlining a word? */
- X#endif
- X register char *bufptr = art_buf;
- X /* pointer to input buffer */
- X register int outpos; /* column position of output */
- X static char prompt_buf[64]; /* place to hold prompt */
- X bool notesfiles = FALSE; /* might there be notesfiles junk? */
- X char oldmode = mode;
- X char *ctime();
- X
- X#ifdef INNERSEARCH
- X register int outputok;
- X#endif
- X
- X if (fstat(fileno(artfp),&filestat))
- X /* get article file stats */
- X return DA_CLEAN;
- X if ((filestat.st_mode & S_IFMT) != S_IFREG)
- X return DA_NORM;
- X artsize = filestat.st_size;
- X /* from that get article size */
- X sprintf(prompt_buf,
- X "%%sEnd of article %ld (of %ld)--what next? [%%s]",
- X (long)art,(long)lastart); /* format prompt string */
- X prompt = prompt_buf;
- X int_count = 0; /* interrupt count is 0 */
- X firstpage = (topline < 0);
- X for (;;) { /* for each page */
- X#ifdef USETHREADS
- X if (ThreadedGroup && max_tree_lines)
- X init_tree(); /* init tree display */
- X#endif
- X assert(art == openart);
- X if (do_fseek) {
- X#ifdef ASYNC_PARSE
- X parse_maybe(art); /* make sure header is ours */
- X#endif
- X artpos = vrdary(artline);
- X if (artpos < 0)
- X artpos = -artpos; /* labs(), anyone? */
- X if (firstpage)
- X artpos = (ART_POS)0;
- X fseek(artfp,artpos,0);
- X if (artpos < htype[PAST_HEADER].ht_minpos)
- X in_header = SOME_LINE;
- X do_fseek = FALSE;
- X restart = Nullch;
- X }
- X linenum = 1;
- X if (firstpage) {
- X if (firstline) {
- X interp(art_buf, (sizeof art_buf), firstline);
- X#ifdef USETHREADS
- X linenum += tree_puts(art_buf,linenum+topline,0);
- X#else
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X fputs(art_buf,stdout) FLUSH;
- X linenum++;
- X#endif
- X artopen(art); /* rewind article in case interp */
- X /* forced a header parse */
- X } else
- X {
- X ART_NUM i;
- X
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X int selected, unseen;
- X
- X selected = curr_p_art
- X && (selected_roots[curr_p_art->root] & 1);
- X unseen = !was_read(art);
- X sprintf(art_buf,"%s%s #%ld",ngname,moderated,(long)art);
- X if (selected_root_cnt) {
- X i = selected_count - (unseen && selected);
- X sprintf(art_buf+strlen(art_buf)," (%ld + %ld more)",
- X (long)i,(long)toread[ng] - selected_count
- X - unthreaded - (!selected && unseen));
- X }
- X else if ((i = (ART_NUM)(toread[ng]-unthreaded-unseen)) != 0)
- X sprintf(art_buf+strlen(art_buf)," (%ld more)",(long)i);
- X linenum += tree_puts(art_buf,linenum+topline,0);
- X }
- X else
- X#endif
- X {
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X printf("Article %ld",(long)art);
- X i = (ART_NUM)(toread[ng] - 1 + was_read(art));
- X#ifdef DELAYMARK
- X if ((i > 0) || dmcount) {
- X printf(" (%ld more",(long)i);
- X if (dmcount)
- X printf(" + %ld Marked to return",(long)dmcount);
- X putchar(')');
- X }
- X#else
- X if (i > 0)
- X printf(" (%ld more)",(long)i);
- X#endif
- X if (htype[NGS_LINE].ht_flags & HT_HIDE)
- X printf(" in %s", ngname);
- X fputs(moderated,stdout);
- X fputs(":\n",stdout) FLUSH;
- X linenum++;
- X }
- X }
- X start_header(art);
- X forcelast = FALSE; /* we will have our day in court */
- X restart = Nullch;
- X artline = 0; /* start counting lines */
- X artpos = 0;
- X vwtary(artline,artpos); /* remember pos in file */
- X }
- X for (; /* linenum already set */
- X in_header || (
- X#ifdef INNERSEARCH
- X innersearch ? innermore() :
- X#endif
- X linenum<(firstpage?initlines:(special?slines:LINES)) );
- X linenum++) { /* for each line on page */
- X if (int_count) { /* exit via interrupt? */
- X putchar('\n') FLUSH; /* get to left margin */
- X int_count = 0; /* reset interrupt count */
- X mode = oldmode;
- X special = FALSE;
- X return DA_NORM; /* skip out of loops */
- X }
- X if (restart) { /* did not finish last line? */
- X bufptr = restart; /* then start again here */
- X restart = Nullch; /* and reset the flag */
- X }
- X else { /* not a restart */
- X if (fgets(art_buf,LBUFLEN,artfp)==Nullch) {
- X /* if all done */
- X mode = oldmode;
- X special = FALSE;
- X return DA_NORM; /* skip out of loops */
- X }
- X bufptr = art_buf; /* so start at beginning */
- X art_buf[LBUFLEN-1] = '\0';
- X /* make sure string ends */
- X }
- X blinebeg = bufptr; /* remember where we began */
- X alinebeg = artpos; /* both in buffer and file */
- X if (in_header && bufptr == art_buf) {
- X hide_this_line =
- X parseline(art_buf,do_hiding,hide_this_line);
- X#ifdef USETHREADS
- X if (!in_header) {
- X linenum += finish_tree(linenum+topline);
- X }
- X#endif
- X } else if (notesfiles && do_hiding &&
- X bufptr == art_buf && *art_buf == '#' &&
- X isupper(art_buf[1]) && art_buf[2] == ':' ) {
- X fgets(art_buf,sizeof(art_buf),artfp);
- X if (index(art_buf,'!') != Nullch)
- X fgets(art_buf,sizeof(art_buf),artfp);
- X htype[PAST_HEADER].ht_minpos = ftell(artfp);
- X /* exclude notesfiles droppings */
- X hide_this_line = TRUE; /* and do not print either */
- X notesfiles = FALSE;
- X }
- X#ifdef CUSTOMLINES
- X if (hideline && bufptr == art_buf &&
- X execute(&hide_compex,art_buf) )
- X hide_this_line = TRUE;
- X#endif
- X if (in_header && htype[in_header].ht_flags & HT_MAGIC) {
- X if (in_header == NGS_LINE) {
- X if ((s = index(art_buf,'\n')) != Nullch)
- X *s = '\0';
- X hide_this_line = (index(art_buf,',') == Nullch)
- X && strEQ(art_buf+12, ngname);
- X if (s != Nullch)
- X *s = '\n';
- X }
- X else if (in_header == EXPIR_LINE) {
- X if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE))
- X hide_this_line = (strlen(art_buf) < 10);
- X }
- X else if (in_header == FROM_LINE) {
- X if (do_hiding && (s = index(art_buf+6,'(')) != Nullch) {
- X strcpy(art_buf+6,s+1);
- X if((s = rindex(art_buf+6,')')) != Nullch)
- X *s = '\0';
- X }
- X }
- X#ifdef USETHREADS
- X else if (in_header == DATE_LINE && curr_p_art && do_hiding) {
- X strftime(art_buf+6, sizeof(art_buf)-6,
- X getval("LOCALTIMEFMT", LOCALTIMEFMT),
- X localtime(&curr_p_art->date));
- X }
- X#endif
- X }
- X if (in_header == SUBJ_LINE &&
- X htype[SUBJ_LINE].ht_flags & HT_MAGIC) {
- X /* is this the subject? */
- X int length;
- X#ifndef USETHREADS
- X char sp;
- X#endif
- X
- X length = strlen(art_buf)-1;
- X artline++;
- X art_buf[length] = '\0'; /* wipe out newline */
- X#ifdef NOFIREWORKS
- X no_ulfire();
- X#endif
- X notesfiles =
- X (instr(&art_buf[length-10]," - (nf", TRUE) != Nullch);
- X#ifdef USETHREADS
- X /* tree_puts(, ,1) underlines subject */
- X linenum += tree_puts(art_buf,linenum+topline,1)-1;
- X#else
- X if (oldsubject) {
- X length += 7;
- X fputs("(SAME) ",stdout);
- X oldsubject = FALSE;
- X }
- X if (length+UG > COLS) { /* rarely true */
- X linenum++;
- X vwtary(artline,vrdary(artline-1)+COLS);
- X artline++;
- X }
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X /* Find the point where the subject text starts. */
- X s = art_buf;
- X if (!isspace(*s)) {
- X /* This is the first subject line, not a continuation
- X line. Skip past the "Subject:" */
- X s += 8;
- X }
- X /* Skip past any whitespace. */
- X while (isspace(*s)) ++s;
- X
- X /* Split the string in two at the whitespace. */
- X sp = *(s-1);
- X *(s-1) = '\0';
- X
- X fputs(art_buf, stdout) FLUSH;
- X
- X /* On an UGly terminal, the start-underline magic cookie
- X takes up space, so we steal a space from the subject
- X line. This is not quite right for tabs; oh well. */
- X if (!UG)
- X putchar(sp);
- X
- X underprint(s); /* print subject underlined */
- X putchar('\n') FLUSH; /* and finish the line */
- X#endif
- X }
- X else if (hide_this_line && do_hiding) {
- X /* do not print line? */
- X linenum--; /* compensate for linenum++ */
- X if (!in_header)
- X hide_this_line = FALSE;
- X }
- X#ifdef USETHREADS
- X else if (in_header) {
- X artline++;
- X linenum += tree_puts(art_buf,linenum+topline,0)-1;
- X }
- X#endif
- X else { /* just a normal line */
- X if (highlight==artline) { /* this line to be highlit? */
- X if (marking == STANDOUT) {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_sofire();
- X#endif
- X standout();
- X }
- X else {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_ulfire();
- X#endif
- X underline();
- X }
- X if (*bufptr == '\n')
- X putchar(' ');
- X }
- X#ifdef INNERSEARCH
- X outputok = !hide_everything;
- X /* get it into register, hopefully */
- X#endif
- X#ifdef CLEAREOL
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X maybe_eol();
- X#endif /* CLEAREOL */
- X#ifdef CUSTOMLINES
- X if (pagestop && bufptr == art_buf &&
- X execute(&page_compex,art_buf) )
- X linenum = 32700;
- X#endif
- X for (outpos = 0; outpos < COLS; ) {
- X /* while line has room */
- X if (*(unsigned char *)bufptr >= ' ') { /* normal char? */
- X#ifdef ULSMARTS
- X if (*bufptr == '_') {
- X if (bufptr[1] == '\b') {
- X if (!under_lining && highlight!=artline
- X#ifdef INNERSEARCH
- X && outputok
- X#endif
- X ) {
- X under_lining++;
- X if (UG) {
- X if (bufptr != buf &&
- X bufptr[-1] == ' ') {
- X outpos--;
- X backspace();
- X }
- X }
- X underline();
- X }
- X bufptr += 2;
- X }
- X }
- X else {
- X if (under_lining) {
- X under_lining = 0;
- X un_underline();
- X if (UG) {
- X if (*bufptr == ' ')
- X goto skip_put;
- X outpos++;
- X }
- X }
- X }
- X#endif
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X {
- X#ifdef ROTATION
- X if (rotate && !in_header
- X && isalpha(*bufptr)) {
- X if ((*bufptr & 31) <= 13)
- X putchar(*bufptr+13);
- X else
- X putchar(*bufptr-13);
- X }
- X else
- X#endif
- X putchar(*bufptr);
- X }
- X if (*UC && ((highlight==artline && marking == 1)
- X#ifdef ULSMARTS
- X || under_lining
- X#endif
- X )) {
- X backspace();
- X underchar();
- X }
- X skip_put:
- X bufptr++;
- X outpos++;
- X }
- X else if (*bufptr == '\n' || !*bufptr) {
- X /* newline? */
- X#ifdef ULSMARTS
- X if (under_lining) {
- X under_lining = 0;
- X un_underline();
- X }
- X#endif
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH && outpos < COLS - 6) {
- X standout();
- X printf("%4d",artline);
- X un_standout();
- X }
- X#endif
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X putchar('\n') FLUSH;
- X restart = 0;
- X outpos = 1000; /* signal normal \n */
- X }
- X else if (*bufptr == '\t') { /* tab? */
- X int incpos = 8 - outpos % 8;
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X if (GT)
- X putchar(*bufptr);
- X else
- X while (incpos--) putchar(' ');
- X bufptr++;
- X outpos += 8 - outpos % 8;
- X }
- X else if (*bufptr == '\f') { /* form feed? */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X fputs("^L",stdout);
- X if (bufptr == blinebeg && highlight != artline)
- X linenum = 32700;
- X /* how is that for a magic number? */
- X bufptr++;
- X outpos += 2;
- X }
- X else { /* other control char */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X {
- X putchar('^');
- X if (highlight == artline && *UC && marking == 1) {
- X backspace();
- X underchar();
- X putchar(*bufptr+64);
- X backspace();
- X underchar();
- X }
- X else
- X putchar(*bufptr+64);
- X }
- X bufptr++;
- X outpos += 2;
- X }
- X
- X } /* end of column loop */
- X
- X if (outpos < 1000) {/* did line overflow? */
- X restart = bufptr;
- X /* restart here next time */
- X if (!AM || XN) {/* no automatic margins on tty? */
- X#ifdef INNERSEARCH /* then move it down ourselves */
- X if (outputok)
- X#endif
- X putchar('\n') FLUSH;
- X }
- X if (*bufptr == '\n') /* skip the newline */
- X restart = 0;
- X }
- X
- X /* handle normal end of output line formalities */
- X
- X if (highlight == artline) {
- X /* were we highlighting line? */
- X if (marking == STANDOUT)
- X un_standout();
- X else
- X un_underline();
- X highlight = -1; /* no more we are */
- X }
- X artline++; /* count the line just printed */
- X if (artline - LINES + 1 > topline)
- X /* did we just scroll top line off? */
- X topline = artline - LINES + 1;
- X /* then recompute top line # */
- X }
- X
- X /* determine actual position in file */
- X
- X if (restart) /* stranded somewhere in the buffer? */
- X artpos += restart - blinebeg;
- X /* just calculate position */
- X else /* no, ftell will do */
- X artpos = ftell(artfp);
- X /* so do ftell */
- X vwtary(artline,artpos); /* remember pos in file */
- X } /* end of line loop */
- X
- X#ifdef INNERSEARCH
- X innersearch = 0;
- X if (hide_everything) {
- X hide_everything = FALSE;
- X *buf = Ctl('l');
- X goto fake_command;
- X }
- X#endif
- X if (linenum >= 32700)/* did last line have formfeed? */
- X vwtary(artline-1,-vrdary(artline-1));
- X /* remember by negating pos in file */
- X
- X special = FALSE; /* end of page, so reset page length */
- X firstpage = FALSE; /* and say it is not 1st time thru */
- X
- X /* extra loop bombout */
- X
- X if (artpos == artsize) {/* did we just now reach EOF? */
- X mode = oldmode;
- X return DA_NORM; /* avoid --MORE--(100%) */
- X }
- X
- X/* not done with this article, so pretend we are a pager */
- X
- reask_pager:
- X unflush_output(); /* disable any ^O in effect */
- X standout(); /* enter standout mode */
- X printf("--MORE--(%ld%%)",(long)(artpos*100/artsize));
- X un_standout(); /* leave standout mode */
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif
- X fflush(stdout);
- X/* reinp_pager: /* unused, commented for lint */
- X eat_typeahead();
- X#ifdef DEBUGGING
- X if (debug & DEB_CHECKPOINTING) {
- X printf("(%d %d %d)",checkcount,linenum,artline);
- X fflush(stdout);
- X }
- X#endif
- X if (checkcount >= docheckwhen &&
- X linenum == LINES &&
- X (artline > 40 || checkcount >= docheckwhen+10) ) {
- X /* while he is reading a whole page */
- X /* in an article he is interested in */
- X checkcount = 0;
- X checkpoint_rc(); /* update .newsrc */
- X }
- X collect_subjects(); /* loads subject cache until */
- X /* input is pending */
- X mode = 'p';
- X getcmd(buf);
- X if (errno) {
- X if (LINES < 100 && !int_count)
- X *buf = '\f';/* on CONT fake up refresh */
- X else {
- X *buf = 'q'; /* on INTR or paper just quit */
- X }
- X }
- X carriage_return();
- X#ifndef CLEAREOL
- X erase_eol(); /* and erase the prompt */
- X#else
- X if (erase_screen && can_home_clear)
- X clear_rest();
- X else
- X erase_eol(); /* and erase the prompt */
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X fflush(stdout);
- X
- X fake_command: /* used by innersearch */
- X#ifdef USETHREADS
- X output_chase_phrase = TRUE;
- X#endif
- X
- X /* parse and process pager command */
- X
- X switch (page_switch()) {
- X case PS_ASK: /* reprompt "--MORE--..." */
- X goto reask_pager;
- X case PS_RAISE: /* reparse on article level */
- X mode = oldmode;
- X return DA_RAISE;
- X case PS_TOEND: /* fast pager loop exit */
- X mode = oldmode;
- X return DA_TOEND;
- X case PS_NORM: /* display more article */
- X break;
- X }
- X } /* end of page loop */
- X}
- X
- X/* process pager commands */
- X
- int
- page_switch()
- X{
- X register char *s;
- X
- X switch (*buf) {
- X case 'd':
- X case Ctl('d'): /* half page */
- X special = TRUE;
- X slines = LINES / 2 + 1;
- X if (marking && *blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X up_line();
- X highlight = --artline;
- X restart = blinebeg;
- X artpos = alinebeg;
- X }
- X return PS_NORM;
- X case '!': /* shell escape */
- X escapade();
- X return PS_ASK;
- X#ifdef INNERSEARCH
- X case Ctl('i'):
- X gline = 3;
- X sprintf(cmd_buf,"^[^%c]",*blinebeg);
- X compile(&gcompex,cmd_buf,TRUE,TRUE);
- X goto caseG;
- X case Ctl('g'):
- X gline = 3;
- X compile(&gcompex,"^Subject:",TRUE,TRUE);
- X goto caseG;
- X case 'g': /* in-article search */
- X if (!finish_command(FALSE))/* get rest of command */
- X return PS_ASK;
- X s = buf+1;
- X if (isspace(*s))
- X s++;
- X if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) {
- X /* compile regular expression */
- X printf("\n%s\n",s) FLUSH;
- X return PS_ASK;
- X }
- X carriage_return();
- X erase_eol(); /* erase the prompt */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X /* FALL THROUGH */
- X caseG:
- X case 'G': {
- X /* ART_LINE lines_to_skip = 0; */
- X ART_POS start_where;
- X
- X if (gline < 0 || gline > LINES-2)
- X gline = LINES-2;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Start here? %d >=? %d\n",topline + gline + 1,artline)
- X FLUSH;
- X#endif
- X if (*buf == Ctl('i') || topline+gline+1 >= artline)
- X start_where = artpos;
- X /* in case we had a line wrap */
- X else {
- X start_where = vrdary(topline+gline+1);
- X if (start_where < 0)
- X start_where = -start_where;
- X }
- X if (start_where < htype[PAST_HEADER].ht_minpos)
- X start_where = htype[PAST_HEADER].ht_minpos;
- X fseek(artfp,(long)start_where,0);
- X innersearch = 0; /* assume not found */
- X while (fgets(buf, sizeof buf, artfp) != Nullch) {
- X /* lines_to_skip++; NOT USED NOW */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Test %s",buf) FLUSH;
- X#endif
- X if (execute(&gcompex,buf) != Nullch) {
- X innersearch = ftell(artfp);
- X break;
- X }
- X }
- X if (!innersearch) {
- X fseek(artfp,artpos,0);
- X fputs("(Not found)",stdout) FLUSH;
- X return PS_ASK;
- X }
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos)
- X FLUSH;
- X#endif
- X if (innersearch <= artpos) { /* already on page? */
- X if (innersearch < artpos) {
- X artline = topline+1;
- X while (vrdary(artline) < innersearch)
- X artline++;
- X }
- X highlight = artline - 1;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("@ %d\n",highlight) FLUSH;
- X#endif
- X topline = highlight - gline;
- X if (topline < -1)
- X topline = -1;
- X *buf = '\f'; /* fake up a refresh */
- X innersearch = 0;
- X return page_switch();
- X }
- X else { /* who knows how many lines it is? */
- X do_fseek = TRUE;
- X hide_everything = TRUE;
- X }
- X return PS_NORM;
- X }
- X#else
- X case 'g': case 'G': case Ctl('g'):
- X notincl("g");
- X return PS_ASK;
- X#endif
- X case '\n': /* one line */
- X special = TRUE;
- X slines = 2;
- X return PS_NORM;
- X#ifdef ROTATION
- X case 'X':
- X rotate = !rotate;
- X /* FALL THROUGH */
- X#endif
- X case 'l':
- X case '\f': /* refresh screen */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH) {
- X printf("Topline = %d",topline) FLUSH;
- X gets(buf);
- X }
- X#endif
- X clear();
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X do_fseek = TRUE;
- X artline = topline;
- X if (artline < 0)
- X artline = 0;
- X firstpage = (topline < 0);
- X return PS_NORM;
- X case 'b':
- X case '\b':
- X case Ctl('b'): { /* back up a page */
- X ART_LINE target;
- X
- X#ifndef CLEAREOL
- X clear();
- X#else
- X if (can_home_clear) /* if we can home do it */
- X home_cursor();
- X else
- X clear();
- X
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X do_fseek = TRUE; /* reposition article file */
- X target = topline - (LINES - 2);
- X artline = topline;
- X if (artline >= 0) do {
- X artline--;
- X } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0);
- X topline = artline;
- X /* remember top line of screen */
- X /* (line # within article file) */
- X if (artline < 0)
- X artline = 0;
- X firstpage = (topline < 0);
- X return PS_NORM;
- X }
- X case 'h': { /* help */
- X int cmd;
- X
- X if ((cmd = help_page()) > 0)
- X pushchar(cmd);
- X return PS_ASK;
- X }
- X#ifdef USETHREADS
- X case 't': /* output thread data */
- X page_line = 1;
- X p_art = curr_p_art;
- X entire_tree();
- X return PS_ASK;
- X#endif
- X case '\177':
- X case '\0': /* treat del,break as 'n' */
- X *buf = 'n';
- X /* FALL THROUGH */
- X case 'k': case 'K':
- X#ifdef USETHREADS
- X case 'T': case 'J':
- X#endif
- X case 'n': case 'N': case Ctl('n'):
- X case 's': case 'S':
- X case 'e':
- X case 'u':
- X case 'w': case 'W':
- X case '|':
- X mark_as_read(); /* mark article as read */
- X /* FALL THROUGH */
- X#ifdef USETHREADS
- X case 'U': case ',':
- X case '<': case '>':
- X case '[': case ']':
- X case '{': case '}':
- X case '+': case ':':
- X#endif
- X case '#':
- X case '$':
- X case '&':
- X case '-':
- X case '.':
- X case '/':
- X case '1': case '2': case '3': case '4': case '5':
- X case '6': case '7': case '8': case '9':
- X case '=':
- X case '?':
- X case 'c': case 'C':
- X#ifdef DEBUGGING
- X case 'D':
- X#endif
- X case 'E':
- X case 'f': case 'F':
- X case 'j':
- X case Ctl('k'):
- X case 'm': case 'M':
- X case 'p': case 'P': case Ctl('p'):
- X case 'Q':
- X case 'r': case 'R': case Ctl('r'):
- X case 'v':
- X case 'Y':
- X#ifndef ROTATION
- X case 'x': case 'X':
- X#endif
- X case Ctl('x'):
- X case 'z':
- X case '^':
- X
- X#ifdef ROTATION
- X rotate = FALSE;
- X#endif
- X reread = FALSE;
- X do_hiding = TRUE;
- X if (index("nNpP\016\020",*buf) == Nullch &&
- X index("wWsSe:!&|/?123456789.",*buf) != Nullch) {
- X setdfltcmd();
- X standout(); /* enter standout mode */
- X printf(prompt,mailcall,dfltcmd);
- X /* print prompt, whatever it is */
- X un_standout(); /* leave standout mode */
- X putchar(' ');
- X fflush(stdout);
- X }
- X return PS_RAISE; /* and pretend we were at end */
- X#ifdef ROTATION
- X case 'x':
- X rotate = TRUE;
- X /* FALL THROUGH */
- X#endif
- X case 'y':
- X case Ctl('v'):
- X /* Leaving it undocumented in case */
- X /* I want to steal the key--LAW */
- X case ' ': /* continue current article */
- X if (erase_screen) { /* -e? */
- X#ifndef CLEAREOL
- X clear(); /* clear screen */
- X#else
- X if (can_home_clear) /* if we can home do it */
- X home_cursor();
- X else
- X clear(); /* else clear screen */
- X
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X fflush(stdout);
- X
- X if (*blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X restart = blinebeg;
- X artline--; /* restart this line */
- X artpos = alinebeg;
- X if (marking) /* and mark repeated line */
- X highlight = artline;
- X }
- X topline = artline;
- X /* and remember top line of screen */
- X /* (line # within article file) */
- X }
- X else if (marking && *blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X /* are we marking repeats? */
- X up_line(); /* go up one line */
- X highlight = --artline;/* and get ready to highlight */
- X restart = blinebeg; /* the old line */
- X artpos = alinebeg;
- X }
- X return PS_NORM;
- X case 'q': /* quit this article? */
- X do_hiding = TRUE;
- X return PS_TOEND;
- X default:
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X return PS_ASK;
- X }
- X}
- X
- X#ifdef INNERSEARCH
- bool
- innermore()
- X{
- X if (artpos < innersearch) { /* not even on page yet? */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch)
- X FLUSH;
- X#endif
- X return TRUE;
- X }
- X if (artpos == innersearch) { /* just got onto page? */
- X isrchline = artline; /* remember first line after */
- X highlight = artline - 1;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("There it is %ld = %ld, %d @ %d\n",(long)artpos,
- X (long)innersearch,hide_everything,highlight) FLUSH;
- X#endif
- X if (hide_everything) { /* forced refresh? */
- X topline = highlight - gline;
- X if (topline < -1)
- X topline = -1;
- X return FALSE; /* let refresh do it all */
- X }
- X }
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Not far enough? %d <? %d + %d\n",artline,isrchline,gline)
- X FLUSH;
- X#endif
- X if (artline < isrchline + gline) {
- X return TRUE;
- X }
- X return FALSE;
- X}
- X#endif
- END_OF_FILE
- if test 25485 -ne `wc -c <'art.c'`; then
- echo shar: \"'art.c'\" unpacked with wrong size!
- fi
- # end of 'art.c'
- fi
- if test -f 'common.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'common.h'\"
- else
- echo shar: Extracting \"'common.h'\" \(26986 characters\)
- sed "s/^X//" >'common.h' <<'END_OF_FILE'
- X/* $Id: common.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
- X *
- X * $Log: common.h,v $
- X * Revision 4.4.2.1 1991/12/01 18:05:42 sob
- X * Patchlevel 2 changes
- X *
- X * Revision 4.4 1991/09/09 20:18:23 sob
- X * release 4.4
- X *
- X *
- X *
- X */
- X/* This software is Copyright 1991 by Stan Barber.
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X */
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <ctype.h>
- X#include "config.h" /* generated by installation script */
- X#ifdef WHOAMI
- X# include <whoami.h>
- X#endif
- X#ifndef isalnum
- X# define isalnum(c) (isalpha(c) || isdigit(c))
- X#endif
- X
- X#include <errno.h>
- X#include <signal.h>
- X#ifdef IOCTL
- X#include <sys/ioctl.h>
- X#endif
- X#ifdef SUNOS4
- X# ifdef sparc /* needed to support vfork call on sparc machines */
- X# include <vfork.h>
- X# endif
- X#endif
- X
- X#ifdef FCNTL
- X# include <fcntl.h>
- X#endif
- X
- X#ifdef TERMIO
- X# include <termio.h>
- X#else
- X# ifdef TERMIOS
- X# include <termios.h>
- X# else
- X# include <sgtty.h>
- X# endif
- X#endif
- X
- X#ifdef GETPWENT
- X# include <pwd.h>
- X#endif
- X
- X#ifdef PTEM
- X#include <sys/stream.h>
- X#include <sys/ptem.h>
- X#endif
- X
- X#define BITSPERBYTE 8
- X#ifdef pdp11
- X#define LBUFLEN 512 /* line buffer length */
- X#else
- X#define LBUFLEN 1024 /* line buffer length */
- X#endif
- X /* (don't worry, .newsrc lines can exceed this) */
- X#ifdef pdp11
- X# define CBUFLEN 256 /* command buffer length */
- X# define PUSHSIZE 128
- X#else
- X# define CBUFLEN 512 /* command buffer length */
- X# define PUSHSIZE 256
- X#endif
- X#ifdef pdp11
- X# define MAXFILENAME 128
- X#else
- X# define MAXFILENAME 512
- X#endif
- X#define LONGKEY 15 /* longest keyword: currently "posting-version" */
- X#define FINISHCMD 0177
- X
- X/* some handy defs */
- X
- X#define bool char
- X#define bool_int int
- X#define char_int int
- X#ifndef TRUE
- X#define TRUE (1)
- X#endif
- X#ifndef FALSE
- X#define FALSE (0)
- X#endif
- X#define Null(t) ((t)0)
- X#define Nullch Null(char *)
- X#define Nullfp Null(FILE *)
- X
- X#define Ctl(ch) (ch & 037)
- X
- X#define strNE(s1,s2) (strcmp(s1,s2))
- X#define strEQ(s1,s2) (!strcmp(s1,s2))
- X#define strnNE(s1,s2,l) (strncmp(s1,s2,l))
- X#define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
- X
- X/* Things we can figure out ourselves */
- X
- X#ifdef SIGTSTP
- X# define BERKELEY /* include job control signals? */
- X#endif
- X
- X#ifdef FIONREAD
- X# define PENDING
- X#else
- X# ifdef O_NDELAY
- X# define PENDING
- X# endif
- X#endif
- X
- X#ifdef EUNICE
- X# define LINKART /* add 1 level of possible indirection */
- X# define UNLINK(victim) while (!unlink(victim))
- X#else
- X# define UNLINK(victim) unlink(victim)
- X#endif
- X
- X/* Valid substitutions for strings marked with % comment are:
- X * %a Current article number
- X * %A Full name of current article (%P/%c/%a)
- X * (if LINKART defined, is the name of the real article)
- X * %b Destination of a save command, a mailbox or command
- X * %B The byte offset to the beginning of the article for saves
- X * with or without the header
- X * %c Current newsgroup, directory form
- X * %C Current newsgroup, dot form
- X * %d %P/%c
- X * %D Old Distribution: line
- X * %e Extract program
- X * %E Extract destination directory
- X * %f Old From: line or Reply-To: line
- X * %F Newsgroups to followup to from Newsgroups: and Followup-To:
- X * %h Name of header file to pass to mail or news poster
- X * %H Host name (yours)
- X * %i Old Message-I.D.: line, with <>
- X * %I Inclusion indicator
- X * %l News administrator login name
- X * %L Login name (yours)
- X * %M Number of articles marked with M
- X * %n Newsgroups from source article
- X * %N Full name (yours)
- X * %o Organization (yours)
- X * %O Original working directory (where you ran rn from)
- X * %p Your private news directory (-d switch)
- X * %P Public news spool directory (SPOOLDIR)
- X * %r Last reference (parent article id)
- X * %R New references list
- X * %s Subject, with all Re's and (nf)'s stripped off
- X * %S Subject, with one Re stripped off
- X * %t New To: line derived from From: and Reply-To (Internet always)
- X * %T New To: line derived from Path:
- X * %u Number of unread articles
- X * %U Number of unread articles disregarding current article
- X * %v Number of unselected articles disregarding current article
- X * %w Mthreads' tmp directory
- X * %W The thread directory root
- X * %x News library directory, usually /usr/lib/news
- X * %X Rn library directory, usually %x/rn
- X * %z Size of current article in bytes.
- X * %Z Number of selected threads.
- X * %~ Home directory
- X * %. Directory containing . files
- X * %# count of articles saved in current command (from 1 to n)
- X * %$ current process number
- X * %{name} Environment variable "name". %{name-default} form allowed.
- X * %[name] Header line beginning with "Name: ", without "Name: "
- X * %"prompt"
- X * Print prompt and insert what is typed.
- X * %`command`
- X * Insert output of command.
- X * %(test_text=pattern?if_text:else_text)
- X * Substitute if_text if test_text matches pattern, otherwise
- X * substitute else_text. Use != for negated match.
- X * % substitutions are done on test_text, if_text, and else_text.
- X * (Note: %() only works if CONDSUB defined.)
- X * %digit Substitute the text matched by the nth bracket in the last
- X * pattern that had brackets. %0 matches the last bracket
- X * matched, in case you had alternatives.
- X *
- X * Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
- X * Put _ in the middle to capitalize last component: %_c = net/Jokes
- X *
- X * ~ interpretation in filename expansion happens after % expansion, so
- X * you could put ~%{NEWSLOGNAME-news} and it will expand correctly.
- X */
- X
- X/* *** System Dependent Stuff *** */
- X
- X/* NOTE: many of these are defined in the config.h file */
- X
- X/* name of organization */
- X#ifndef ORGNAME
- X# define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota"
- X#endif
- X
- X#ifndef MBOXCHAR
- X# define MBOXCHAR 'F' /* how to recognize a mailbox by 1st char */
- X#endif
- X
- X#ifndef ROOTID
- X# define ROOTID 0 /* uid of superuser */
- X#endif
- X
- X#ifdef NORMSIG
- X# define sigset signal
- X# define sigignore(sig) signal(sig,SIG_IGN)
- X#endif
- X
- X#ifndef LOGDIRFIELD
- X# define LOGDIRFIELD 6 /* Which field (origin 1) is the */
- X /* login directory in /etc/passwd? */
- X /* (If it is not kept in passwd, */
- X /* but getpwnam() returns it, */
- X /* define the symbol GETPWENT) */
- X#endif
- X#ifndef GCOSFIELD
- X# define GCOSFIELD 5
- X#endif
- X
- X#ifndef NEGCHAR
- X# define NEGCHAR '!'
- X#endif
- X
- X/* Space conservation section */
- X
- X/* To save D space, cut down size of NGMAX and VARYSIZE. */
- X#define NGMAX 100 /* number of newsgroups allowed on command line */
- X /* undefine ONLY symbol to disable "only" feature */
- X#define VARYSIZE 256 /* this makes a block 1024 bytes long in DECville */
- X /* (used by virtual array routines) */
- X
- X/* Undefine any of the following features to save both I and D space */
- X/* In general, earlier ones are easier to get along without */
- X/* Pdp11's without split I and D may have to undefine them all */
- X#define DEBUGGING /* include debugging code */
- X#define USETHREADS /* Add article-thread following */
- X#define CUSTOMLINES /* include code for HIDELINE and PAGESTOP */
- X#define PUSHBACK /* macros and keymaps using pushback buffer */
- X#define SPEEDOVERMEM /* use more memory to run faster */
- X#define WORDERASE /* enable ^W to erase a word */
- X#define MAILCALL /* check periodically for mail */
- X#define CLEAREOL /* use clear to end-of-line instead of clear screen */
- X#define NOFIREWORKS /* keep whole screen from flashing on certain */
- X /* terminals such as older Televideos */
- X#define VERIFY /* echo the command they just typed */
- X#define HASHNG /* hash newsgroup lines for fast lookup-- */
- X /* linear search used if not defined */
- X#define CONDSUB /* allow %(cond?text:text) */
- X#define BACKTICK /* allow %`command` */
- X#define PROMPTTTY /* allow %"prompt" */
- X#define ULSMARTS /* catch _^H in text and do underlining */
- X#define TERMMOD /* allow terminal type modifier on switches */
- X#define BAUDMOD /* allow baudrate modifier on switches */
- X#define GETLOGIN /* use getlogin() routine as backup to environment */
- X /* variables USER or LOGNAME */
- X#define ORGFILE /* if organization begins with /, look up in file */
- X#define TILDENAME /* allow ~logname expansion */
- X#define SETENV /* allow command line environment variable setting */
- X#define MAKEDIR /* use our makedir() instead of shell script */
- X#define MEMHELP /* keep help messages in memory */
- X#define VERBOSE /* compile in more informative messages */
- X#define TERSE /* compile in shorter messages */
- X /* (Note: both VERBOSE and TERSE can be defined; -t
- X * sets terse mode. One or the other MUST be defined.
- X */
- X#ifndef pdp11
- X# define CACHESUBJ /* cache subject lines in memory */
- X /* without this ^N still works but runs really slow */
- X /* but you save lots and lots of D space */
- X# define CACHEFIRST /* keep absolute first article numbers in memory */
- X /* cost: about 2k */
- X#endif
- X#define ROTATION /* enable x, X and ^X commands to work */
- X#define DELBOGUS /* ask if bogus newsgroups should be deleted */
- X#define RELOCATE /* allow newsgroup rearranging */
- X#define ESCSUBS /* escape substitutions in multi-character commands */
- X#define DELAYMARK /* allow articles to be temporarily marked as read */
- X /* until exit from current newsgroup or Y command */
- X#undef MCHASE /* unmark xrefed articles on m or M */
- X#define MUNGHEADER /* allow alternate header formatting via */
- X /* environment variable ALTHEADER (not impl) */
- X#define ASYNC_PARSE /* allow parsing headers asyncronously to reading */
- X /* used by MCHASE and MUNGHEADER */
- X#define FINDNEWNG /* check for new newsgroups on startup */
- X#define FASTNEW /* do optimizations on FINDNEWNG for faster startup */
- X /* (this optimization can make occasional mistakes */
- X /* if a group is removed and another group of the */
- X /* same length is added, and if no softpointers are */
- X /* affected by said change.) */
- X#define INNERSEARCH /* search command 'g' with article */
- X#define CATCHUP /* catchup command at newsgroup level */
- X#define NGSEARCH /* newsgroup pattern matching */
- X#define ONLY /* newsgroup restrictions by pattern */
- X#define KILLFILES /* automatic article killer files */
- X#define ARTSEARCH /* pattern searches among articles */
- X /* /, ?, ^N, ^P, k, K */
- X
- X/* some dependencies among options */
- X
- X#ifndef ARTSEARCH
- X# undef KILLFILES
- X# undef INNERSEARCH
- X# undef CACHESUBJ
- X#endif
- X
- X#ifndef DELAYMARK
- X# ifndef MCHASE
- X# ifndef MUNGHEADER
- X# undef ASYNC_PARSE
- X# endif
- X# endif
- X#endif
- X
- X#ifndef SETUIDGID
- X# define eaccess access
- X#endif
- X
- X#ifdef ONLY /* idiot lint doesn't grok #if */
- X# define NGSORONLY
- X#else
- X# ifdef NGSEARCH
- X# define NGSORONLY
- X# endif
- X#endif
- X
- X#ifdef VERBOSE
- X# ifdef TERSE
- X# define IF(c) if (c)
- X# define ELSE else
- X# else
- X# define IF(c)
- X# define ELSE
- X# endif
- X#else /* !VERBOSE */
- X# ifndef TERSE
- X# define TERSE
- X# endif
- X# define IF(c) "IF" outside of VERBOSE???
- X# define ELSE "ELSE" outside of VERBOSE???
- X#endif
- X
- X#ifdef DEBUGGING
- X# define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}}
- X#else
- X# define assert(ex) ;
- X#endif
- X
- X#ifdef SPEEDOVERMEM
- X# define OFFSET(x) (x)
- X#else
- X# define OFFSET(x) ((x)-absfirst)
- X#endif
- X
- X/* If you're strapped for space use the help messages in shell scripts */
- X/* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */
- X#ifdef MEMHELP /* undef MEMHELP above to get them all as sh scripts */
- X# undef NGHELP
- X# undef ARTHELP
- X# undef PAGERHELP
- X# undef SUBSHELP
- X#else
- X# ifndef NGHELP /* % and ~ */
- X# define NGHELP "%X/ng.help"
- X# endif
- X# ifndef ARTHELP /* % and ~ */
- X# define ARTHELP "%X/art.help"
- X# endif
- X# ifndef PAGERHELP /* % and ~ */
- X# define PAGERHELP "%X/pager.help"
- X# endif
- X# ifndef SUBSHELP /* % and ~ */
- X# define SUBSHELP "%X/subs.help"
- X# endif
- X#endif
- X
- X#ifdef CLEAREOL
- X# define TCSIZE 512 /* capacity for termcap strings */
- X#else
- X# ifdef pdp11
- X# define TCSIZE 256 /* capacity for termcap strings */
- X# else
- X# define TCSIZE 512 /* capacity for termcap srings */
- X# endif
- X#endif
- X
- X/* Additional ideas:
- X * Make the do_newsgroup() routine a separate process.
- X * Keep .newsrc on disk instead of in memory.
- X * Overlays, if you have them.
- X * Get a bigger machine.
- X */
- X
- X/* End of Space Conservation Section */
- X
- X/* More System Dependencies */
- X
- X/* news library */
- X#ifndef LIB /* ~ and %l only ("~%l" is permissable) */
- X# define LIB "/usr/lib/news"
- X#endif
- X
- X/* path to private executables */
- X#ifndef RNLIB /* ~, %x and %l only */
- X# define RNLIB "%x/trn"
- X#endif
- X
- X/* system-wide RNINIT switches */
- X#ifndef GLOBINIT
- X# define GLOBINIT "%X/INIT"
- X#endif
- X
- X/* where to find news files */
- X#ifndef SPOOL /* % and ~ */
- X# define SPOOL "/usr/spool/news"
- X#endif
- X
- X#ifdef USETHREADS
- X# ifdef THREAD_DIR
- X# ifdef LONG_THREAD_NAMES
- X# undef SUFFIX
- X# else
- X# ifndef SUFFIX
- X# define SUFFIX ".th"
- X# endif
- X# endif
- X# else
- X# define THREAD_DIR SPOOL
- X# ifndef SUFFIX
- X# define SUFFIX "/.thread"
- X# endif
- X# undef LONG_THREAD_NAMES
- X# endif
- X# ifndef NEW_THREAD
- X# define NEW_THREAD ".new"
- X# endif
- X#endif
- X
- X/* default characters to use in the selection menu */
- X#ifndef SELECTCHARS
- X# define SELECTCHARS "abcdefgijlorstuvwxz1234567890"
- X#endif
- X
- X/* file containing list of active newsgroups and max article numbers */
- X#ifndef ACTIVE /* % and ~ */
- X# define ACTIVE "%x/active"
- X#endif
- X#ifdef SERVER
- X# ifndef ACTIVE1
- X# define ACTIVE1 "%w/active1"
- X# endif
- X#endif
- X#ifndef ACTIVE2
- X# define ACTIVE2 "%w/active2"
- X#endif
- X#ifndef DBINIT
- X# define DBINIT "%W/db.init"
- X#endif
- X#ifndef MTPRELOCK
- X# define MTPRELOCK "%w/LOCK"
- X#endif
- X#ifndef MTLOCK
- X# define MTLOCK "%w/LOCKmthreads"
- X#endif
- X#ifndef MTDLOCK
- X# define MTDLOCK "%w/LOCKmtdaemon"
- X#endif
- X#ifndef MTLOG
- X# define MTLOG "%w/mt.log"
- X#endif
- X
- X#if !defined(SERVER) && defined(XTHREAD)
- X# undef XTHREAD
- X#endif
- X
- X/* location of history file */
- X#ifndef ARTFILE /* % and ~ */
- X# define ARTFILE "%x/history"
- X#endif
- X
- X/* command to setup a new .newsrc */
- X#ifndef NEWSETUP /* % and ~ */
- X# define NEWSETUP "newsetup"
- X#endif
- X
- X/* command to display a list of un-subscribed-to newsgroups */
- X#ifndef NEWSGROUPS /* % and ~ */
- X# define NEWSGROUPS "newsgroups"
- X#endif
- X
- X/* preferred shell for use in doshell routine */
- X/* ksh or sh would be okay here */
- X#ifndef PREFSHELL
- X# define PREFSHELL "/bin/csh"
- X#endif
- X
- X/* path to fastest starting shell */
- X#ifndef SH
- X# define SH "/bin/sh"
- X#endif
- X
- X/* default unshar'ing program */
- X#ifndef UNSHAR
- X# define UNSHAR "/bin/sh"
- X#endif
- X
- X/* path to default editor */
- X#ifndef DEFEDITOR
- X# define DEFEDITOR "/usr/ucb/vi"
- X#endif
- X
- X/* location of macro file */
- X#ifndef RNMACRO
- X# ifdef PUSHBACK
- X# define RNMACRO "%./.rnmac"
- X# endif
- X#endif
- X
- X/* location of full name */
- X#ifndef FULLNAMEFILE
- X# ifndef PASSNAMES
- X# define FULLNAMEFILE "%./.fullname"
- X# endif
- X#endif
- X
- X/* virtual array file name template */
- X#ifndef VARYNAME /* % and ~ */
- X# define VARYNAME "/tmp/rnvary.%$"
- X#endif
- X
- X/* where to compile a new newsgroup list */
- X#ifndef RNEWNAME
- X# define RNEWNAME "/tmp/rnew.%$"
- X#endif
- X
- X/* file to pass header to followup article poster */
- X#ifndef HEADNAME /* % and ~ */
- X# define HEADNAME "%./.rnhead"
- X/* or alternately #define HEADNAME "/tmp/rnhead.%$" */
- X#endif
- X
- X#ifndef MAKEDIR
- X/* shell script to make n-deep subdirectories */
- X# ifndef DIRMAKER /* % and ~ */
- X# define DIRMAKER "%X/makedir"
- X# endif
- X#endif
- X
- X/* location of newsrc file */
- X#ifndef RCNAME /* % and ~ */
- X# define RCNAME "%./.newsrc"
- X#endif
- X
- X/* temporary newsrc file in case we crash while writing out */
- X#ifndef RCTNAME /* % and ~ */
- X# define RCTNAME "%./.newnewsrc"
- X#endif
- X
- X/* newsrc file at the beginning of this session */
- X#ifndef RCBNAME /* % and ~ */
- X# define RCBNAME "%./.oldnewsrc"
- X#endif
- X
- X/* if existent, contains process number of current or crashed rn */
- X#ifndef LOCKNAME /* % and ~ */
- X# define LOCKNAME "%./.rnlock"
- X#endif
- X
- X/* information from last invocation of rn */
- X#ifndef LASTNAME /* % and ~ */
- X# define LASTNAME "%./.rnlast"
- X#endif
- X
- X/* file with soft pointers into the active file */
- X#ifndef SOFTNAME /* % and ~ */
- X# define SOFTNAME "%./.rnsoft"
- X#endif
- X
- X/* list of article numbers to mark as unread later (see M and Y cmmands) */
- X#ifndef RNDELNAME /* % and ~ */
- X# define RNDELNAME "%./.rndelay"
- X#endif
- X
- X/* a motd-like file for rn */
- X#ifndef NEWSNEWSNAME /* % and ~ */
- X# define NEWSNEWSNAME "%X/newsnews"
- X#endif
- X
- X/* command to send a reply */
- X#ifndef MAILPOSTER /* % and ~ */
- X# define MAILPOSTER "Rnmail -h %h"
- X#endif
- X
- X#ifdef INTERNET
- X# ifndef MAILHEADER /* % */
- X# ifdef CONDSUB
- X# define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
- X# else
- X# define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
- X# endif
- X# endif
- X#else
- X# ifndef MAILHEADER /* % */
- X# ifdef CONDSUB
- X# define MAILHEADER "To: %T\nSubject: %(%i=^$?:Re: %S\nNewsgroups: %n\nIn-Reply-To: %i)\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
- X# else
- X# define MAILHEADER "To: %T\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
- X# endif
- X# endif
- X#endif
- X
- X#ifndef YOUSAID /* % */
- X# define YOUSAID "In article %i you write:"
- X#endif
- X
- X/* command to submit a followup article */
- X#ifndef NEWSPOSTER /* % and ~ */
- X# define NEWSPOSTER "Pnews -h %h"
- X#endif
- X
- X#ifndef NEWSHEADER /* % */
- X# ifdef CONDSUB
- X#ifdef INTERNET
- X# define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
- X#else
- X# define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
- X#endif
- X# else
- X# ifdef INTERNET
- X# define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
- X# else
- X# define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
- X# endif
- X# endif
- X#endif
- X
- X#ifndef ATTRIBUTION /* % */
- X# define ATTRIBUTION "In article %i %f writes:"
- X#endif
- X
- X#ifndef PIPESAVER /* % */
- X# ifdef CONDSUB
- X# ifdef SERVER
- X# define PIPESAVER "%(%B=^0$?<%P/rrn%a.%$:tail +%Bc %P/rrn%a.%$ |) %b"
- X# else
- X# define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b"
- X# endif
- X# else
- X# ifdef SERVER
- X# define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b"
- X# else
- X# define PIPESAVER "tail +%Bc %A | %b"
- X# endif
- X# endif
- X#endif
- X
- X#ifndef EXSAVER
- X# ifdef SERVER
- X# define EXSAVER "tail +%Bc %P/rrn%a.%$ | %e"
- X# else
- X# define EXSAVER "tail +%Bc %A | %e"
- X# endif
- X#endif
- X
- X#ifndef NORMSAVER /* % and ~ */
- X# ifdef SERVER
- X# define NORMSAVER "%X/norm.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\""
- X# else
- X# define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\""
- X# endif
- X#endif
- X
- X#ifndef MBOXSAVER /* % and ~ */
- X# ifdef MININACT /* 2.10.2 site? */
- X# ifdef SERVER
- X# define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\""
- X# else
- X# define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\""
- X# endif
- X# else
- X# ifdef CONDSUB
- X# ifdef SERVER
- X# define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\""
- X# else
- X# define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\""
- X# endif
- X /* header munging with a vengeance */
- X# else
- X# ifdef SERVER
- X# define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %[posted]\""
- X# else
- X# define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\""
- X# endif
- X# endif
- X# endif
- X#endif
- X
- X#ifdef MKDIRS
- X
- X# ifndef SAVEDIR /* % and ~ */
- X# define SAVEDIR "%p/%c"
- X# endif
- X# ifndef SAVENAME /* % */
- X# define SAVENAME "%a"
- X# endif
- X
- X#else
- X
- X# ifndef SAVEDIR /* % and ~ */
- X# define SAVEDIR "%p"
- X# endif
- X# ifndef SAVENAME /* % */
- X# define SAVENAME "%^C"
- X# endif
- X
- X#endif
- X
- X#ifndef KILLGLOBAL /* % and ~ */
- X# define KILLGLOBAL "%p/KILL"
- X#endif
- X
- X#ifndef KILLLOCAL /* % and ~ */
- X# define KILLLOCAL "%p/%c/KILL"
- X#endif
- X
- X/* how to cancel an article */
- X#ifndef CANCEL
- X# ifdef MININACT /* 2.10.2 ? */
- X# define CANCEL "%x/inews -h < %h"
- X# else
- X# define CANCEL "inews -h < %h"
- X# endif
- X#endif
- X
- X/* how to cancel an article, continued */
- X#ifndef CANCELHEADER
- X#ifdef INTERNET
- X# define CANCELHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\n%i was cancelled from within trn.\n"
- X#else
- X# define CANCELHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\n%i was cancelled from within trn.\n"
- X#endif
- X#endif
- X
- X/* how to supersede an article */
- X#ifndef SUPERSEDEHEADER
- X#ifdef INTERNET
- X# define SUPERSEDEHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSupersedes: %i\nSubject: %S\nDistribution: %D\nOrganization: %o\n"
- X#else
- X# define SUPERSEDEHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSupersedes: %i\nSubject: %S\nDistribution: %D\nOrganization: %o\n"
- X#endif
- X#endif
- X
- X#ifndef LOCALTIMEFMT
- X# define LOCALTIMEFMT "%a %b %d %X %Z %Y"
- X#endif
- X
- X/* where to find the mail file */
- X#ifndef MAILFILE
- X# define MAILFILE "/usr/spool/mail/%L"
- X#endif
- X
- X/* how to open binary format files */
- X#ifndef FOPEN_RB
- X# define FOPEN_RB "r"
- X#endif
- X#ifndef FOPEN_WB
- X# define FOPEN_WB "w"
- X#endif
- X
- X/* what to do with ansi prototypes -- '()' == ignore, 'x' == use */
- X#ifndef ANSI
- X# ifdef __STDC__
- X# define ANSI(x) x
- X# else
- X# define ANSI(x) ()
- X# endif
- X#endif
- X
- X/* how many characters is a newline in a text file? */
- X#ifndef NL_SIZE
- X# define NL_SIZE 1
- X#endif
- X
- X/* some important types */
- X
- typedef int NG_NUM; /* newsgroup number */
- typedef long ART_NUM; /* article number */
- X#ifdef pdp11
- X typedef short ART_UNREAD; /* ordinarily this should be long */
- X /* like ART_NUM, but assuming that */
- X /* we stay less than 32767 articles */
- X /* behind saves a lot of space. */
- X /* NOTE: do not make unsigned. */
- X#else
- X typedef long ART_UNREAD;
- X#endif
- X#ifdef SERVER
- typedef int ART_PART; /* for passing to nntpopen() */
- X#endif
- typedef long ART_POS; /* char position in article file */
- typedef int ART_LINE; /* line position in article file */
- typedef long ACT_POS; /* char position in active file */
- typedef unsigned int MEM_SIZE; /* for passing to malloc */
- X
- X
- X/* *** end of the machine dependent stuff *** */
- X
- X/* GLOBAL THINGS */
- X
- X/* file statistics area */
- X
- XEXT struct stat filestat;
- X
- X/* various things of type char */
- X
- char *index();
- char *rindex();
- char *getenv();
- char *strcat();
- char *strcpy();
- X
- XEXT char buf[LBUFLEN+1]; /* general purpose line buffer */
- XEXT char cmd_buf[CBUFLEN]; /* buffer for formatting system commands */
- XEXT char *indstr INIT(">"); /* indent for old article embedded in followup */
- X
- XEXT char *cwd INIT(Nullch); /* current working directory */
- XEXT char *dfltcmd INIT(Nullch); /* 1st char is default command */
- X
- X/* switches */
- X
- X#ifdef DEBUGGING
- X EXT int debug INIT(0); /* -D */
- X# define DEB_NNTP 16
- X# define DEB_INNERSRCH 32
- X# define DEB_FILEXP 64
- X# define DEB_HASH 128
- X# define DEB_XREF_MARKER 256
- X# define DEB_CTLAREA_BITMAP 512
- X# define DEB_SOFT_POINTERS 1024
- X# define DEB_NEWSRC_LINE 2048
- X# define DEB_SEARCH_AHEAD 4096
- X# define DEB_CHECKPOINTING 8192
- X# define DEB_FEED_XREF 16384
- X#endif
- X
- X#ifdef ARTSEARCH
- X EXT int scanon INIT(0); /* -S */
- X#endif
- X
- X#ifdef USETHREADS
- X EXT bool use_threads INIT(THREAD_INIT); /* -x */
- X EXT int max_tree_lines INIT(6);
- X EXT char select_order[4] INIT("lsm");
- X EXT int select_on INIT(SELECT_INIT); /* -X */
- X EXT char end_select INIT('Z');
- X EXT char page_select INIT('>');
- X#endif
- X
- XEXT bool mbox_always INIT(FALSE); /* -M */
- XEXT bool norm_always INIT(FALSE); /* -N */
- XEXT bool thread_always INIT(FALSE); /* -a */
- XEXT bool olden_days INIT(FALSE); /* -o */
- XEXT bool checkflag INIT(FALSE); /* -c */
- XEXT bool suppress_cn INIT(FALSE); /* -s */
- XEXT int countdown INIT(5); /* how many lines to list before invoking -s */
- XEXT bool muck_up_clear INIT(FALSE); /* -loco */
- XEXT bool erase_screen INIT(FALSE); /* -e */
- X#if defined(CLEAREOL) || defined(USETHREADS)
- XEXT bool can_home INIT(FALSE);
- X#endif
- X#ifdef CLEAREOL
- XEXT bool can_home_clear INIT(FALSE); /* fancy -e */
- X#endif
- XEXT bool findlast INIT(FALSE); /* -r */
- XEXT bool typeahead INIT(FALSE); /* -T */
- X#ifdef VERBOSE
- X# ifdef TERSE
- X EXT bool verbose INIT(TRUE); /* +t */
- X# endif
- X#endif
- X#ifdef VERIFY
- X EXT bool verify INIT(FALSE); /* -v */
- X#endif
- X EXT bool quickstart INIT(FALSE); /* -q */
- X
- X#define NOMARKING 0
- X#define STANDOUT 1
- X#define UNDERLINE 2
- XEXT int marking INIT(NOMARKING); /* -m */
- X
- XEXT ART_LINE initlines INIT(0); /* -i */
- XEXT bool initlines_specified INIT(FALSE);
- X
- X/* miscellania */
- X
- int fseek();
- long atol(), ftell();
- XEXT bool in_ng INIT(FALSE); /* current state of rn */
- XEXT char mode INIT('i'); /* current state of rn */
- X
- XEXT FILE *tmpfp INIT(Nullfp); /* scratch fp used for .rnlock, .rnlast, etc. */
- X
- XEXT NG_NUM nextrcline INIT(0); /* 1st unused slot in rcline array */
- X /* startup to avoid checking twice in a row */
- X
- extern errno;
- X/* Factored strings */
- X
- XEXT char nullstr[1] INIT("");
- XEXT char sh[] INIT(SH);
- XEXT char defeditor[] INIT(DEFEDITOR);
- XEXT char hforhelp[] INIT("Type h for help.\n");
- X#ifdef STRICTCR
- XEXT char badcr[] INIT("\nUnnecessary CR ignored.\n");
- X#endif
- XEXT char readerr[] INIT("rn read error");
- XEXT char unsubto[] INIT("\n\nUnsubscribed to newsgroup %s\n");
- XEXT char cantopen[] INIT("Can't open %s\n");
- XEXT char cantcreate[] INIT("Can't create %s\n");
- XEXT char cantrecreate[] INIT("Can't recreate %s -- restoring older version.\n");
- X
- X#ifdef VERBOSE
- X EXT char nocd[] INIT("Can't chdir to directory %s\n");
- X#else
- X EXT char nocd[] INIT("Can't find %s\n");
- X#endif
- X
- X#ifdef NOLINEBUF
- X#define FLUSH ,fflush(stdout)
- X#else
- X#define FLUSH
- X#endif
- X
- X#ifdef lint
- X#undef FLUSH
- X#define FLUSH
- X#undef putchar
- X#define putchar(c)
- X#endif
- END_OF_FILE
- if test 26986 -ne `wc -c <'common.h'`; then
- echo shar: \"'common.h'\" unpacked with wrong size!
- fi
- # end of 'common.h'
- fi
- if test -f 'term.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'term.c'\"
- else
- echo shar: Extracting \"'term.c'\" \(26055 characters\)
- sed "s/^X//" >'term.c' <<'END_OF_FILE'
- X/* $Id: term.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
- X *
- X * $Log: term.c,v $
- X * Revision 4.4.2.1 1991/12/01 18:05:42 sob
- X * Patchlevel 2 changes
- X *
- X * Revision 4.4 1991/09/09 20:27:37 sob
- X * release 4.4
- X *
- X *
- X *
- X */
- X/* This software is Copyright 1991 by Stan Barber.
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X */
- X
- X#include "EXTERN.h"
- X#include "common.h"
- X#include "util.h"
- X#include "final.h"
- X#include "help.h"
- X#include "cheat.h"
- X#include "intrp.h"
- X#include "INTERN.h"
- X#include "term.h"
- X
- char ERASECH; /* rubout character */
- char KILLCH; /* line delete character */
- char tcarea[TCSIZE]; /* area for "compiled" termcap strings */
- X
- X#ifdef USETHREADS
- int upcost;
- X#endif
- X
- X/* guarantee capability pointer != Nullch */
- X/* (I believe terminfo will ignore the &tmpaddr argument.) */
- X
- X#define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
- X
- X#ifdef PUSHBACK
- struct keymap {
- X char km_type[128];
- X union km_union {
- X struct keymap *km_km;
- X char *km_str;
- X } km_ptr[128];
- X};
- X
- X#define KM_NOTHIN 0
- X#define KM_STRING 1
- X#define KM_KEYMAP 2
- X#define KM_BOGUS 3
- X
- X#define KM_TMASK 3
- X#define KM_GSHIFT 4
- X#define KM_GMASK 7
- X
- typedef struct keymap KEYMAP;
- X
- KEYMAP *topmap INIT(Null(KEYMAP*));
- X
- void mac_init();
- KEYMAP *newkeymap();
- void show_keymap();
- void pushstring();
- X#endif
- X
- void line_col_calcs();
- X
- X/* terminal initialization */
- X
- void
- term_init()
- X{
- X savetty(); /* remember current tty state */
- X
- X#ifdef TERMIO
- X outspeed = _tty.c_cflag & CBAUD; /* for tputs() */
- X ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- X KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
- X if (GT = ((_tty.c_oflag & TABDLY) != TAB3))
- X /* we have tabs, so that's OK */;
- X else
- X _tty.c_oflag &= ~TAB3; /* turn off kernel tabbing -- done in rn */
- X#else /* !TERMIO */
- X# ifdef TERMIOS
- X outspeed = cfgetospeed(&_tty); /* for tputs() (output) */
- X ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- X KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
- X/* _tty.c_oflag &= ~OXTABS; /* turn off kernel tabbing-done in rn */
- X# else /* !TERMIOS */
- X outspeed = _tty.sg_ospeed; /* for tputs() */
- X ERASECH = _tty.sg_erase; /* for finish_command() */
- X KILLCH = _tty.sg_kill; /* for finish_command() */
- X if (GT = ((_tty.sg_flags & XTABS) != XTABS))
- X /* we have tabs, so that's OK */;
- X else
- X _tty.sg_flags &= ~XTABS;
- X# endif /* TERMIOS */
- X#endif /* TERMIO */
- X
- X /* The following could be a table but I can't be sure that there isn't */
- X /* some degree of sparsity out there in the world. */
- X
- X switch (outspeed) { /* 1 second of padding */
- X#ifdef BEXTA
- X case BEXTA: just_a_sec = 1920; break;
- X#else
- X#ifdef B19200
- X case B19200: just_a_sec = 1920; break;
- X#endif
- X#endif
- X case B9600: just_a_sec = 960; break;
- X case B4800: just_a_sec = 480; break;
- X case B2400: just_a_sec = 240; break;
- X case B1800: just_a_sec = 180; break;
- X case B1200: just_a_sec = 120; break;
- X case B600: just_a_sec = 60; break;
- X case B300: just_a_sec = 30; break;
- X /* do I really have to type the rest of this??? */
- X case B200: just_a_sec = 20; break;
- X case B150: just_a_sec = 15; break;
- X case B134: just_a_sec = 13; break;
- X case B110: just_a_sec = 11; break;
- X case B75: just_a_sec = 8; break;
- X case B50: just_a_sec = 5; break;
- X default: just_a_sec = 960; break;
- X /* if we are running detached I */
- X } /* don't want to know about it! */
- X}
- X
- X/* set terminal characteristics */
- X
- void
- term_set(tcbuf)
- char *tcbuf; /* temp area for "uncompiled" termcap entry */
- X{
- X char *tmpaddr; /* must not be register */
- X register char *tmpstr;
- X char *tgetstr();
- X char *s;
- X int status;
- X#ifdef TIOCGWINSZ
- X struct winsize winsize;
- X#endif
- X
- X#ifdef PENDING
- X#if ! defined (FIONREAD) && ! defined (RDCHK)
- X /* do no delay reads on something that always gets closed on exit */
- X
- X devtty = open("/dev/tty",0);
- X if (devtty < 0) {
- X printf(cantopen,"/dev/tty") FLUSH;
- X finalize(1);
- X }
- X fcntl(devtty,F_SETFL,O_NDELAY);
- X#endif
- X#endif
- X
- X /* get all that good termcap stuff */
- X
- X#ifdef HAVETERMLIB
- X status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
- X if (status < 1) {
- X#ifdef VERBOSE
- X printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
- X#else
- X fputs("Termcap botch\n",stdout) FLUSH;
- X#endif
- X finalize(1);
- X }
- X tmpaddr = tcarea; /* set up strange tgetstr pointer */
- X s = Tgetstr("pc"); /* get pad character */
- X PC = *s; /* get it where tputs wants it */
- X if (!tgetflag("bs")) { /* is backspace not used? */
- X BC = Tgetstr("bc"); /* find out what is */
- X if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */
- X BC = Tgetstr("le");
- X } else
- X BC = "\b"; /* make a backspace handy */
- X UP = Tgetstr("up"); /* move up a line */
- X if (!*UP) /* no UP string? */
- X marking = 0; /* disable any marking */
- X if (muck_up_clear) /* this is for weird HPs */
- X CL = "\n\n\n\n";
- X else
- X CL = Tgetstr("cl"); /* get clear string */
- X CE = Tgetstr("ce"); /* clear to end of line string */
- X TI = Tgetstr("ti"); /* initialize display */
- X TE = Tgetstr("te"); /* reset display */
- X#if defined(CLEAREOL) || defined(USETHREADS)
- X HO = Tgetstr("ho"); /* home cursor if no CM */
- X CM = Tgetstr("cm"); /* cursor motion */
- X if (*CM || *HO)
- X can_home = TRUE;
- X#endif
- X#ifdef CLEAREOL
- X CD = Tgetstr("cd"); /* clear to end of display */
- X if (!*CE || !*CD || !can_home) /* can we CE, CD, and home? */
- X can_home_clear = FALSE; /* no, so disable use of clear eol */
- X if (!*CE) CE = CD;
- X#endif /* CLEAREOL */
- X#ifdef USETHREADS
- X upcost = strlen(UP);
- X#endif
- X SO = Tgetstr("so"); /* begin standout */
- X SE = Tgetstr("se"); /* end standout */
- X if ((SG = tgetnum("sg"))<0)
- X SG = 0; /* blanks left by SG, SE */
- X US = Tgetstr("us"); /* start underline */
- X UE = Tgetstr("ue"); /* end underline */
- X if ((UG = tgetnum("ug"))<0)
- X UG = 0; /* blanks left by US, UE */
- X if (*US)
- X UC = nullstr; /* UC must not be NULL */
- X else
- X UC = Tgetstr("uc"); /* underline a character */
- X if (!*US && !*UC) { /* no underline mode? */
- X US = SO; /* substitute standout mode */
- X UE = SE;
- X UG = SG;
- X }
- X LINES = tgetnum("li"); /* lines per page */
- X COLS = tgetnum("co"); /* columns on page */
- X
- X#ifdef TIOCGWINSZ
- X { struct winsize ws;
- X if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- X LINES = ws.ws_row;
- X COLS = ws.ws_col;
- X }
- X }
- X#endif
- X
- X AM = tgetflag("am"); /* terminal wraps automatically? */
- X XN = tgetflag("xn"); /* then eats next newline? */
- X VB = Tgetstr("vb");
- X if (!*VB)
- X VB = "\007";
- X CR = Tgetstr("cr");
- X if (!*CR) {
- X if (tgetflag("nc") && *UP) {
- X CR = safemalloc((MEM_SIZE)strlen(UP)+2);
- X sprintf(CR,"%s\r",UP);
- X }
- X else
- X CR = "\r";
- X }
- X#ifdef TIOCGWINSZ
- X if (ioctl(1, TIOCGWINSZ, &winsize)>=0) {
- X if (winsize.ws_row>0) LINES=winsize.ws_row;
- X if (winsize.ws_col>0) COLS=winsize.ws_col;
- X }
- X#endif
- X#else
- X ?????? /* Roll your own... */
- X#endif
- X termlib_init();
- X line_col_calcs();
- X noecho(); /* turn off echo */
- X crmode(); /* enter cbreak mode */
- X
- X#ifdef PUSHBACK
- X mac_init(tcbuf);
- X#endif
- X}
- X
- X#ifdef PUSHBACK
- void
- mac_init(tcbuf)
- char *tcbuf;
- X{
- X char tmpbuf[1024];
- X
- X tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
- X if (tmpfp != Nullfp) {
- X while (fgets(tcbuf,1024,tmpfp) != Nullch) {
- X mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
- X }
- X fclose(tmpfp);
- X }
- X}
- X
- void
- mac_line(line,tmpbuf,tbsize)
- char *line;
- char *tmpbuf;
- int tbsize;
- X{
- X register char *s, *m;
- X register KEYMAP *curmap;
- X register int ch;
- X register int garbage = 0;
- X static char override[] = "\nkeymap overrides string\n";
- X
- X if (topmap == Null(KEYMAP*))
- X topmap = newkeymap();
- X if (*line == '#' || *line == '\n')
- X return;
- X if (line[ch = strlen(line)-1] == '\n')
- X line[ch] = '\0';
- X m = dointerp(tmpbuf,tbsize,line," \t");
- X if (!*m)
- X return;
- X while (*m == ' ' || *m == '\t') m++;
- X for (s=tmpbuf,curmap=topmap; *s; s++) {
- X ch = *s & 0177;
- X if (s[1] == '+' && isdigit(s[2])) {
- X s += 2;
- X garbage = (*s & KM_GMASK) << KM_GSHIFT;
- X }
- X else
- X garbage = 0;
- X if (s[1]) {
- X if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
- X fputs(override,stdout) FLUSH;
- X free(curmap->km_ptr[ch].km_str);
- X curmap->km_ptr[ch].km_str = Nullch;
- X }
- X curmap->km_type[ch] = KM_KEYMAP + garbage;
- X if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
- X curmap->km_ptr[ch].km_km = newkeymap();
- X curmap = curmap->km_ptr[ch].km_km;
- X }
- X else {
- X if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
- X fputs(override,stdout) FLUSH;
- X else {
- X curmap->km_type[ch] = KM_STRING + garbage;
- X curmap->km_ptr[ch].km_str = savestr(m);
- X }
- X }
- X }
- X}
- X
- KEYMAP*
- newkeymap()
- X{
- X register int i;
- X register KEYMAP *map;
- X
- X#ifndef lint
- X map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
- X#else
- X map = Null(KEYMAP*);
- X#endif /* lint */
- X for (i=127; i>=0; --i) {
- X map->km_ptr[i].km_km = Null(KEYMAP*);
- X map->km_type[i] = KM_NOTHIN;
- X }
- X return map;
- X}
- X
- void
- show_macros()
- X{
- X char prebuf[64];
- X
- X if (topmap != Null(KEYMAP*)) {
- X print_lines("Macros:\n",STANDOUT);
- X *prebuf = '\0';
- X show_keymap(topmap,prebuf);
- X }
- X else {
- X print_lines("No macros defined.\n", NOMARKING);
- X }
- X}
- X
- void
- show_keymap(curmap,prefix)
- register KEYMAP *curmap;
- char *prefix;
- X{
- X register int i;
- X register char *next = prefix + strlen(prefix);
- X register int kt;
- X
- X for (i=0; i<128; i++) {
- X if (kt = curmap->km_type[i]) {
- X if (i < ' ')
- X sprintf(next,"^%c",i+64);
- X else if (i == ' ')
- X strcpy(next,"\\040");
- X else if (i == 127)
- X strcpy(next,"^?");
- X else
- X sprintf(next,"%c",i);
- X if ((kt >> KM_GSHIFT) & KM_GMASK) {
- X sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
- X strcat(next,cmd_buf);
- X }
- X switch (kt & KM_TMASK) {
- X case KM_NOTHIN:
- X sprintf(cmd_buf,"%s %c\n",prefix,i);
- X print_lines(cmd_buf,NOMARKING);
- X break;
- X case KM_KEYMAP:
- X show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
- X break;
- X case KM_STRING:
- X sprintf(cmd_buf,"%s %s\n",prefix,curmap->km_ptr[i].km_str);
- X print_lines(cmd_buf,NOMARKING);
- X break;
- X case KM_BOGUS:
- X sprintf(cmd_buf,"%s BOGUS\n",prefix);
- X print_lines(cmd_buf,STANDOUT);
- X break;
- X }
- X }
- X }
- X}
- X
- X#endif
- X
- X/* routine to pass to tputs */
- X
- char
- putchr(ch)
- register char_int ch;
- X{
- X putchar(ch);
- X#ifdef lint
- X ch = Null(char);
- X ch = ch;
- X#endif
- X return((char) 0);
- X}
- X
- X/* input the 2nd and succeeding characters of a multi-character command */
- X/* returns TRUE if command finished, FALSE if they rubbed out first character */
- X
- bool
- finish_command(donewline)
- int donewline;
- X{
- X register char *s;
- X register bool quoteone = FALSE;
- X
- X s = buf;
- X if (s[1] != FINISHCMD) /* someone faking up a command? */
- X return TRUE;
- X do {
- X top:
- X if (*(unsigned char *)s < ' ') {
- X putchar('^');
- X putchar(*s | 64);
- X }
- X else if (*s == '\177') {
- X putchar('^');
- X putchar('?');
- X }
- X else
- X putchar(*s); /* echo previous character */
- X s++;
- re_read:
- X fflush(stdout);
- X getcmd(s);
- X if (quoteone) {
- X quoteone = FALSE;
- X continue;
- X }
- X if (errno || *s == '\f') {
- X *s = Ctl('r'); /* force rewrite on CONT */
- X }
- X if (*s == '\033') { /* substitution desired? */
- X#ifdef ESCSUBS
- X char tmpbuf[4], *cpybuf;
- X
- X tmpbuf[0] = '%';
- X read_tty(&tmpbuf[1],1);
- X#ifdef RAWONLY
- X tmpbuf[1] &= 0177;
- X#endif
- X tmpbuf[2] = '\0';
- X if (tmpbuf[1] == 'h') {
- X (void) help_subs();
- X *s = '\0';
- X reprint();
- X goto re_read;
- X }
- X else if (tmpbuf[1] == '\033') {
- X *s = '\0';
- X cpybuf = savestr(buf);
- X interp(buf, (sizeof buf), cpybuf);
- X free(cpybuf);
- X s = buf + strlen(buf);
- X reprint();
- X goto re_read;
- X }
- X else {
- X interp(s,(sizeof buf) - (s-buf),tmpbuf);
- X fputs(s,stdout);
- X s += strlen(s);
- X }
- X goto re_read;
- X#else
- X notincl("^[");
- X *s = '\0';
- X reprint();
- X goto re_read;
- X#endif
- X }
- X else if (*s == ERASECH) { /* they want to rubout a char? */
- X rubout();
- X s--; /* discount the char rubbed out */
- X if (*(unsigned char *)s < ' ' || *s == '\177')
- X rubout();
- X if (s == buf) { /* entire string gone? */
- X fflush(stdout); /* return to single char command mode */
- X return FALSE;
- X }
- X else
- X goto re_read;
- X }
- X else if (*s == KILLCH) { /* wipe out the whole line? */
- X while (s-- != buf) { /* emulate that many ERASEs */
- X rubout();
- X if (*(unsigned char *)s < ' ' || *s == '\177')
- X rubout();
- X }
- X fflush(stdout);
- X return FALSE; /* return to single char mode */
- X }
- X#ifdef WORDERASE
- X else if (*s == Ctl('w')) { /* wipe out one word? */
- X *s-- = ' ';
- X while (!isspace(*s) || isspace(s[1])) {
- X rubout();
- X if (s-- == buf) {
- X fflush(stdout);
- X return FALSE; /* return to single char mode */
- X }
- X if (*(unsigned char *)s < ' ' || *s == '\177')
- X rubout();
- X }
- X s++;
- X goto re_read;
- X }
- X#endif
- X else if (*s == Ctl('r')) {
- X *s = '\0';
- X reprint();
- X goto re_read;
- X }
- X else if (*s == Ctl('v')) {
- X putchar('^');
- X backspace();
- X fflush(stdout);
- X getcmd(s);
- X goto top;
- X }
- X else if (*s == '\\') {
- X quoteone = TRUE;
- X }
- X#ifdef cray
- X } while (*s != '\r'); /* till a newline (not echoed) */
- X#else
- X } while (*s != '\n'); /* till a newline (not echoed) */
- X#endif
- X *s = '\0'; /* terminate the string nicely */
- X if (donewline)
- X putchar('\n') FLUSH;
- X return TRUE; /* say we succeeded */
- X}
- X
- X/* discard any characters typed ahead */
- X
- void
- eat_typeahead()
- X{
- X#ifdef PUSHBACK
- X if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
- X#else
- X if (!typeahead)
- X#endif
- X {
- X#ifdef PENDING
- X while (input_pending())
- X read_tty(buf,sizeof(buf));
- X#else /* this is probably v7 */
- X#if defined(TERMIO) || defined(TERMIOS)
- X ioctl(_tty_ch,TCSETAW,&_tty);
- X#else
- X ioctl(_tty_ch,TIOCSETP,&_tty);
- X#endif
- X#endif
- X }
- X}
- X
- void
- settle_down()
- X{
- X dingaling();
- X fflush(stdout);
- X/* sleep(1); */
- X#ifdef PUSHBACK
- X nextout = nextin; /* empty circlebuf */
- X#endif
- X eat_typeahead();
- X}
- X
- X#ifdef PUSHBACK
- X/* read a character from the terminal, with multi-character pushback */
- X
- int
- read_tty(addr,size)
- char *addr;
- int size;
- X{
- X if (nextout != nextin) {
- X *addr = circlebuf[nextout++];
- X nextout %= PUSHSIZE;
- X return 1;
- X }
- X else {
- X size = read(0,addr,size);
- X#ifdef RAWONLY
- X *addr &= 0177;
- X#endif
- X return size;
- X }
- X}
- X
- X#ifdef PENDING
- X#if ! defined (FIONREAD) && ! defined (RDCHK)
- int
- circfill()
- X{
- X register int Howmany;
- X
- X errno = 0;
- X Howmany = read(devtty,circlebuf+nextin,1);
- X
- X if (Howmany < 0 && (errno == EAGAIN || errno == EINTR))
- X Howmany = 0;
- X if (Howmany) {
- X nextin += Howmany;
- X nextin %= PUSHSIZE;
- X }
- X return Howmany;
- X}
- X#endif /* PENDING */
- X#endif /* FIONREAD */
- X
- void
- pushchar(c)
- char_int c;
- X{
- X nextout--;
- X if (nextout < 0)
- X nextout = PUSHSIZE - 1;
- X if (nextout == nextin) {
- X fputs("\npushback buffer overflow\n",stdout) FLUSH;
- X sig_catcher(0);
- X }
- X circlebuf[nextout] = c;
- X}
- X
- X#else /* PUSHBACK */
- X#ifndef read_tty
- X/* read a character from the terminal, with hacks for O_NDELAY reads */
- X
- int
- read_tty(addr,size)
- char *addr;
- int size;
- X{
- X if (is_input) {
- X *addr = pending_ch;
- X is_input = FALSE;
- X return 1;
- X }
- X else {
- X size = read(0,addr,size);
- X#ifdef RAWONLY
- X *addr &= 0177;
- X#endif
- X return size;
- X }
- X}
- X#endif /* read_tty */
- X#endif /* PUSHBACK */
- X
- X/* print an underlined string, one way or another */
- X
- void
- underprint(s)
- register char *s;
- X{
- X assert(UC);
- X if (*UC) { /* char by char underline? */
- X while (*s) {
- X if (*(unsigned char *)s < ' ') {
- X putchar('^');
- X backspace();/* back up over it */
- X underchar();/* and do the underline */
- X putchar(*s+64);
- X backspace();/* back up over it */
- X underchar();/* and do the underline */
- X }
- X else {
- X putchar(*s);
- X backspace();/* back up over it */
- X underchar();/* and do the underline */
- X }
- X s++;
- X }
- X }
- X else { /* start and stop underline */
- X underline(); /* start underlining */
- X while (*s) {
- X if (*(unsigned char *)s < ' ') {
- X putchar('^');
- X putchar(*s+64);
- X }
- X else
- X putchar(*s);
- X s++;
- X }
- X un_underline(); /* stop underlining */
- X }
- X}
- X
- X/* keep screen from flashing strangely on magic cookie terminals */
- X
- X#ifdef NOFIREWORKS
- void
- no_sofire()
- X{
- X if (*UP && *SE) { /* should we disable fireworks? */
- X putchar('\n');
- X un_standout();
- X up_line();
- X carriage_return();
- X }
- X}
- X
- void
- no_ulfire()
- X{
- X if (*UP && *US) { /* should we disable fireworks? */
- X putchar('\n');
- X un_underline();
- X up_line();
- X carriage_return();
- X }
- X}
- X#endif
- X
- X/* get a character into a buffer */
- X
- void
- getcmd(whatbuf)
- register char *whatbuf;
- X{
- X#ifdef PUSHBACK
- X register KEYMAP *curmap;
- X register int i;
- X bool no_macros;
- X int times = 0; /* loop detector */
- X char scrchar;
- X
- tryagain:
- X curmap = topmap;
- X no_macros = (whatbuf != buf && nextin == nextout);
- X#endif
- X for (;;) {
- X int_count = 0;
- X errno = 0;
- X if (read_tty(whatbuf,1) < 0){
- X if (!errno)
- X errno = EINTR;
- X if (errno == EINTR)
- X return;
- X perror(readerr);
- X sig_catcher(0);
- X }
- X#ifdef PUSHBACK
- X if (*whatbuf & 0200 || no_macros) {
- X *whatbuf &= 0177;
- X goto got_canonical;
- X }
- X if (curmap == Null(KEYMAP*))
- X goto got_canonical;
- X for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
- X read_tty(&scrchar,1);
- X }
- X switch (curmap->km_type[*whatbuf] & KM_TMASK) {
- X case KM_NOTHIN: /* no entry? */
- X if (curmap == topmap) /* unmapped canonical */
- X goto got_canonical;
- X settle_down();
- X goto tryagain;
- X case KM_KEYMAP: /* another keymap? */
- X curmap = curmap->km_ptr[*whatbuf].km_km;
- X assert(curmap != Null(KEYMAP*));
- X break;
- X case KM_STRING: /* a string? */
- X pushstring(curmap->km_ptr[*whatbuf].km_str);
- X if (++times > 20) { /* loop? */
- X fputs("\nmacro loop?\n",stdout);
- X settle_down();
- X }
- X no_macros = FALSE;
- X goto tryagain;
- X }
- X#else
- X#ifdef RAWONLY
- X *whatbuf &= 0177;
- X#endif
- X break;
- X#endif
- X }
- X
- got_canonical:
- X#if !defined(TERMIO) && !defined(TERMIOS)
- X if (*whatbuf == '\r')
- X *whatbuf = '\n';
- X#endif
- X if (whatbuf == buf)
- X whatbuf[1] = FINISHCMD; /* tell finish_command to work */
- X}
- X
- X#ifdef PUSHBACK
- void
- pushstring(str)
- char *str;
- X{
- X register int i;
- X char tmpbuf[PUSHSIZE];
- X register char *s = tmpbuf;
- X
- X assert(str != Nullch);
- X interp(s,PUSHSIZE,str);
- X for (i = strlen(s)-1; i >= 0; --i) {
- X s[i] ^= 0200;
- X pushchar(s[i]);
- X }
- X}
- X#endif
- X
- int
- get_anything()
- X{
- X char tmpbuf[2];
- X
- reask_anything:
- X unflush_output(); /* disable any ^O in effect */
- X standout();
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("[Type space to continue] ",stdout);
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("[MORE] ",stdout);
- X#endif
- X un_standout();
- X fflush(stdout);
- X eat_typeahead();
- X if (int_count) {
- X return -1;
- X }
- X collect_subjects(); /* loads subject cache until */
- X /* input is pending */
- X getcmd(tmpbuf);
- X if (errno || *tmpbuf == '\f') {
- X putchar('\n') FLUSH; /* if return from stop signal */
- X goto reask_anything; /* give them a prompt again */
- X }
- X if (*tmpbuf == 'h') {
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
- X#endif
- X goto reask_anything;
- X }
- X else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
- X carriage_return();
- X erase_eol(); /* erase the prompt */
- X carriage_return();
- X return *tmpbuf == 'q' ? -1 : *tmpbuf;
- X }
- X if (*tmpbuf == '\n') {
- X page_line = LINES - 1;
- X carriage_return();
- X erase_eol();
- X carriage_return();
- X }
- X else {
- X page_line = 1;
- X if (erase_screen) /* -e? */
- X clear(); /* clear screen */
- X else {
- X carriage_return();
- X erase_eol(); /* erase the prompt */
- X carriage_return();
- X }
- X }
- X return 0;
- X}
- X
- X#ifdef USETHREADS
- int
- pause_getcmd()
- X{
- X unflush_output(); /* disable any ^O in effect */
- X standout();
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("[Type space or a command] ",stdout);
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("[CMD] ",stdout);
- X#endif
- X un_standout();
- X fflush(stdout);
- X eat_typeahead();
- X if (int_count) {
- X return -1;
- X }
- X getcmd(buf);
- X if (errno || *buf == '\f') {
- X return 0; /* if return from stop signal */
- X }
- X else if (*buf != ' ') {
- X carriage_return();
- X erase_eol(); /* erase the prompt */
- X carriage_return();
- X return *buf;
- X }
- X return 0;
- X}
- X#endif
- X
- void
- in_char(prompt, newmode)
- char *prompt;
- char_int newmode;
- X{
- X char oldmode = mode;
- X
- reask_in_char:
- X unflush_output(); /* disable any ^O in effect */
- X fputs(prompt,stdout);
- X fflush(stdout);
- X eat_typeahead();
- X mode = newmode;
- X getcmd(buf);
- X if (errno || *buf == '\f') {
- X putchar('\n') FLUSH; /* if return from stop signal */
- X goto reask_in_char; /* give them a prompt again */
- X }
- X mode = oldmode;
- X}
- X
- int
- print_lines(what_to_print,hilite)
- char *what_to_print;
- int hilite;
- X{
- X register char *s;
- X register int i;
- X
- X if (page_line < 0) /* they do not want to see this? */
- X return -1;
- X for (s=what_to_print; *s; ) {
- X if (page_line >= LINES || int_count) {
- X if (i = -1, int_count || (i = get_anything())) {
- X page_line = -1; /* disable further print_lines */
- X return i;
- X }
- X }
- X page_line++;
- X if (hilite == STANDOUT) {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_sofire();
- X#endif
- X standout();
- X }
- X else if (hilite == UNDERLINE) {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_ulfire();
- X#endif
- X underline();
- X }
- X for (i=0; i<COLS; i++) {
- X if (!*s)
- X break;
- X if (*(unsigned char *)s >= ' ')
- X putchar(*s);
- X else if (*s == '\t') {
- X putchar(*s);
- X i = ((i+8) & ~7) - 1;
- X }
- X else if (*s == '\n') {
- X i = 32000;
- X }
- X else {
- X i++;
- X putchar('^');
- X putchar(*s + 64);
- X }
- X s++;
- X }
- X if (i) {
- X if (hilite == STANDOUT)
- X un_standout();
- X else if (hilite == UNDERLINE)
- X un_underline();
- X if (AM && i == COLS)
- X fflush(stdout);
- X else
- X putchar('\n') FLUSH;
- X }
- X }
- X return 0;
- X}
- X
- void
- page_init()
- X{
- X page_line = 1;
- X if (erase_screen)
- X clear();
- X else
- X putchar('\n') FLUSH;
- X}
- X
- void
- pad(num)
- int num;
- X{
- X register int i;
- X
- X for (i = num; i; --i)
- X putchar(PC);
- X fflush(stdout);
- X}
- X
- X/* echo the command just typed */
- X
- X#ifdef VERIFY
- void
- printcmd()
- X{
- X if (verify && buf[1] == FINISHCMD) {
- X if (*(unsigned char *)buf < ' ') {
- X putchar('^');
- X putchar(*buf | 64);
- X backspace();
- X backspace();
- X }
- X else {
- X putchar(*buf);
- X backspace();
- X }
- X fflush(stdout);
- X }
- X}
- X#endif
- X
- void
- rubout()
- X{
- X backspace(); /* do the old backspace, */
- X putchar(' '); /* space, */
- X backspace(); /* backspace trick */
- X}
- X
- void
- reprint()
- X{
- X register char *s;
- X
- X fputs("^R\n",stdout) FLUSH;
- X for (s = buf; *s; s++) {
- X if (*(unsigned char *)s < ' ') {
- X putchar('^');
- X putchar(*s | 64);
- X }
- X else
- X putchar(*s);
- X }
- X}
- X
- X#if defined(CLEAREOL) || defined(USETHREADS)
- void
- home_cursor()
- X{
- X char *tgoto();
- X
- X if (!*HO) { /* no home sequence? */
- X if (!*CM) { /* no cursor motion either? */
- X fputs ("\n\n\n", stdout);
- X return; /* forget it. */
- X }
- X tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */
- X return;
- X }
- X else { /* we have home sequence */
- X tputs (HO, 1, putchr); /* home via HO */
- X }
- X}
- X#endif
- X
- X#ifdef USETHREADS
- void
- goto_line(from,to) /* assumes caller is already at beginning of line */
- int from,to;
- X{
- X char *tgoto(), *str;
- X int cmcost;
- X
- X if (from == to) {
- X return;
- X }
- X if (*CM && !muck_up_clear) {
- X cmcost = strlen(str = tgoto(CM,0,to));
- X } else {
- X cmcost = 9999;
- X }
- X if (to > from) {
- X go_down:
- X if (to - from <= cmcost) {
- X while(from++ < to) {
- X putchar('\n');
- X }
- X return;
- X }
- X } else if(*UP) {
- X if ((from - to) * upcost <= cmcost) {
- X while(from-- > to) {
- X tputs(UP,1,putchr);
- X }
- X return;
- X }
- X } else if (cmcost == 9999) {
- X home_cursor();
- X from = 0;
- X goto go_down;
- X }
- X tputs(str,1,putchr);
- X}
- X#endif
- X
- void
- line_col_calcs()
- X{
- X if (LINES > 0) { /* is this a crt? */
- X if ((!initlines) || (!initlines_specified))
- X /* no -i or unreasonable value for initlines */
- X if (outspeed >= B9600) /* whole page at >= 9600 baud */
- X initlines = LINES;
- X else if (outspeed >= B4800)/* 16 lines at 4800 */
- X initlines = 16;
- X else /* otherwise just header */
- X initlines = 8;
- X }
- X else { /* not a crt */
- X LINES = 30000; /* so don't page */
- X CL = "\n\n"; /* put a couple of lines between */
- X if ((!initlines) || (!initlines_specified))
- X /* make initlines reasonable */
- X initlines = 8;
- X }
- X if (COLS <= 0)
- X COLS = 80;
- X}
- X
- X
- X#ifdef SIGWINCH
- SIGRET
- winch_catcher()
- X{
- X /* Reset signal in case of System V dain bramage */
- X sigset(SIGWINCH, winch_catcher);
- X
- X /* Come here if window size change signal received */
- X#ifdef TIOCGWINSZ
- X { struct winsize ws;
- X if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- X LINES = ws.ws_row;
- X COLS = ws.ws_col;
- X line_col_calcs();
- X }
- X }
- X#else
- X /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */
- X /* almost certainly something wrong. Figure it out for yourself, */
- X /* because I don't know now to deal :-) */
- X#endif
- X}
- X#endif
- void
- termlib_init()
- X{
- X#ifdef USETITE
- X if (TI && *TI)
- X tputs (TI,1,putchr);
- X#endif
- X return;
- X}
- void
- termlib_reset()
- X{
- X#ifdef USETITE
- X if (TE && *TE)
- X tputs (TE,1,putchr);
- X#endif
- X return;
- X}
- END_OF_FILE
- if test 26055 -ne `wc -c <'term.c'`; then
- echo shar: \"'term.c'\" unpacked with wrong size!
- fi
- # end of 'term.c'
- fi
- echo shar: End of archive 8 \(of 13\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 13 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-